package com.captechconsulting.security; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.Period; import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.security.GeneralSecurityException; @Component public class HeaderUtil { private static final Logger LOG = LoggerFactory.getLogger(HeaderUtil.class); private EncryptionUtil encryptionUtil = new EncryptionUtil(); private static final String HEADER_NAME = "X-Auth-Token"; private Period sessionMaxAge; private String seed; @Autowired private Environment environment; @PostConstruct private void init() { String encryptionEnabled = environment.getProperty("auth.encryption.enabled"); if (StringUtils.isNotBlank(encryptionEnabled) && Boolean.parseBoolean(encryptionEnabled)) { encryptionUtil.encryptionEnabled(true); seed = environment.getRequiredProperty("auth.encryption.seed"); } sessionMaxAge = getSessionMaxAge(); } public String getUserName(HttpServletRequest request) { String header = request.getHeader(HEADER_NAME); return StringUtils.isNotBlank(header) ? extractUserName(header) : null; } private String extractUserName(String value) { try { String decryptedValue = encryptionUtil.decrypt(value, seed); String[] split = decryptedValue.split("\\|"); String username = split[0]; DateTime timestamp = new DateTime(Long.parseLong(split[1])); if (timestamp.isAfter(DateTime.now().minus(sessionMaxAge))) { return username; } } catch (IOException | GeneralSecurityException e) { LOG.debug("Unable to decrypt header", e); } return null; } public void addHeader(HttpServletResponse response, String userName) { try { String encryptedValue = createAuthToken(userName); response.setHeader(HEADER_NAME, encryptedValue); } catch (IOException | GeneralSecurityException e) { LOG.error("Unable to encrypt header", e); } } public String createAuthToken(String userName) throws IOException, GeneralSecurityException { String value = userName + "|" + System.currentTimeMillis(); return encryptionUtil.encrypt(value, seed); } private Period getSessionMaxAge() { String maxAge = environment.getRequiredProperty("auth.session.maxAge"); PeriodFormatter format = new PeriodFormatterBuilder() .appendDays() .appendSuffix("d", "d") .printZeroRarelyFirst() .appendHours() .appendSuffix("h", "h") .printZeroRarelyFirst() .appendMinutes() .appendSuffix("m", "m") .toFormatter(); Period sessionMaxAge = format.parsePeriod(maxAge); if (LOG.isDebugEnabled()) { LOG.debug("Session maxAge is: "+ formatIfNotZero(sessionMaxAge.getDays(), "days", "day") + formatIfNotZero(sessionMaxAge.getHours(), "hours", "hour") + formatIfNotZero(sessionMaxAge.getMinutes(), "minutes", "minute") ); } return sessionMaxAge; } private static String formatIfNotZero(int value, String plural, String singleton) { if (value > 0) { if (value > 1) { return "" + value + " " + plural; } return "" + value + " " + singleton; } return ""; } }